// ignore_for_file: file_names, slash_for_doc_comments, must_call_super, unnecessary_overrides, override_on_non_overriding_member, must_be_immutable, prefer_const_constructors, sized_box_for_whitespace, avoid_unnecessary_containers, avoid_print

import 'package:desktop_webview_window/desktop_webview_window.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:webview_window_example/config/ConfigVal.dart';
import 'package:webview_window_example/pages/appin/AppInTranslatePage.dart';
import 'package:webview_window_example/entity/TranslateEntity.dart';

import 'dart:async';
import 'dart:io';

import 'package:mybase/base/tool/empty/FFEmpty.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';

import 'package:crypto/crypto.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mybase/base/tool/file/FFile.dart';
import 'dart:convert';

import 'package:webview_window_example/windows/SelectMdMapWindow.dart';

import '../../utils/CommonUtils.dart';

extension AppInEvent on AppInTranslatePageState {
  ///开始
  void onStart() async {
    if (FFEmpty.stringIsEmpty(textController.text)) {
      SmartDialog.showToast("待翻译的值不能为空啊");
      return;
    }

    webview = await WebviewWindow.create(
      configuration: CreateConfiguration(
          userDataFolderWindows: await _getWebViewPath(),
          titleBarTopPadding: Platform.isMacOS ? 20 : 0,
          windowWidth: 600,
          windowHeight: 600),
      iWebview: this,
    );
    TranslateEntity entity = entitys[selectIndex];

    webview
      ..setBrightness(Brightness.dark)
      ..launch(getUrl(entity.urlCode, Uri.encodeFull(textController.text)))
      ..addOnUrlRequestCallback((url) {
        debugPrint('snjj addOnUrlRequestCallback = $url');
      })
      ..addOnWebMessageReceivedCallback((message) {
        print("snjj addOnWebMessageReceivedCallback = $message");
      })
      ..onClose.whenComplete(() {
        debugPrint("snjj whenComplete");
      });
  }

  onNext() {
    selectIndex++;
    if (selectIndex >= entitys.length) {
      selectIndex = 0;
    }
    setState(() {});
  }

  Future<String> _getWebViewPath() async {
    final document = await getApplicationDocumentsDirectory();
    String path = p.join(
      document.path,
      'desktop_webview_window',
    );
    print("path = $path");
    return path;
  }

  //提取翻译文字
  extractTranslate() async {
    extractTranslateHandler();
  }

  extractTranslateHandler() async {
    String? value;
    try {
      /// 识别google翻译
      String js = """
        function ycss() {
            var str = "";
            var array = document.getElementsByClassName('ryNqvb');
            for (let index = 0; index < array.length; index++) {
                const element = array[index];
                var elementStr = element.innerHTML;
                str =  str + elementStr;
            }
            return str;
        }

        ycss();
        // alert(ycss());
      """;

      /// 识别Deeple翻译
      // String js = """
      //   function ycss() {
      //       var str = "";
      //       var array = document.getElementsByClassName('--l sentence_highlight');
      //       var from = array.length * 0.5;
      //       for (let index = from; index < array.length; index++) {
      //           const element = array[index];
      //           var elementStr = element.innerHTML;
      //           str =  str + elementStr;
      //       }
      //       return str;
      //   }

      // ycss();
      // alert(ycss());
      // """;

      value = await webview.evaluateJavaScript(js);
      int times = 0;
      while (times < 3) {
        await Future.delayed(Duration(seconds: 1));
        value = await webview.evaluateJavaScript(js);
        print('尝试第${times + 1}次解析--------------------------value:$value');
        if (!FFEmpty.stringIsEmpty(value)) break;
        times++;
      }
    } catch (e) {
      debugPrint('evaluateJavaScript error: $e');
    }

    print('最终结果--------------------------value:$value');
    if (FFEmpty.stringIsEmpty(value)) {
      // didFinished(0);
      SmartDialog.showToast("出现问题，请注意",
          displayTime: Duration(milliseconds: 1000));
      return;
    }

    ///如果是德语，转换双引号
    TranslateEntity entity = entitys[selectIndex];
    if (entity.code == "de") {
      value = value!.replaceAll("“", "\"");
      value = value.replaceAll("„", "\"");
    }

    ///如果是俄语，转换« »
    if (entity.code == "er") {
      value = value!.replaceAll("«", "\"");
      value = value.replaceAll("»", "\"");
    }

    ///如果右括号左边就是逗号，则去掉
    int index = value!.lastIndexOf(",");
    print("index = $index   ,,, lenth = ${value.length}");
    if (value.length - index <= 5) {
      value = value.replaceRange(index, index + 1, "");
    }

    //校验一下对错
    if (checkTranslate(value) == false) {
      SmartDialog.showToast("待翻译的英文格式不对",
          displayTime: Duration(milliseconds: 1000));
      // webview.close();
      return;
    }

    final jsonObject = json.decode(value);
    final formattedJsonString =
        JsonEncoder.withIndent('  ').convert(jsonObject);

    resultController.text = formattedJsonString;
    webview.close();
  }

  //校验翻译的合法性
  bool checkTranslate(String text) {
    bool ok = false;
    try {
      Map<String, dynamic> md5Map = json.decode(text);
      ok = true;
    } catch (e) {
      print("解析出错了");
    }

    return ok;
  }

  onClickWrite() async {
    if (FFEmpty.stringIsEmpty(resultController.text)) {
      SmartDialog.showToast("结果为空啊");
      return;
    }

    if (!checkTranslate(resultController.text)) {
      SmartDialog.showToast("数据不是标准的json格式");
      return;
    }

    if (FFEmpty.stringIsEmpty(targetDir)) {
      SmartDialog.showToast("目标目录为空");
      return;
    }

    write(resultController.text);
  }

  onSelectTargetFile() async {
    String? selectedDirectory = await FilePicker.platform
        .getDirectoryPath(initialDirectory: ConfigVal.osDir);

    if (FFEmpty.stringIsEmpty(selectedDirectory)) {
      SmartDialog.showToast("目标目录选择失败");
      return;
    }

    targetDir = selectedDirectory;
    setState(() {});
  }

  onSelectMapKey() async {
    if (FFEmpty.stringIsEmpty(targetDir)) {
      SmartDialog.showToast("language目录未选择",
          displayTime: Duration(milliseconds: 250));
      return;
    }

    String enPath = "${targetDir}/zh-Hans.json";
    bool exist = await FFile.isExistFile(enPath);

    if (exist == false) {
      SmartDialog.showToast("language/zh-Hans.json文件不存在",
          displayTime: Duration(milliseconds: 250));
      return;
    }

    //弹窗
    SmartDialog.show(
      alignment: Alignment.topCenter,
      builder: (ctx) {
        return SelectMdMapWindow(
          mapFile: enPath,
          onFinish: (str) {
            final jsonObject = json.decode(str);
            final formattedJsonString =
                JsonEncoder.withIndent('  ').convert(jsonObject);
            textController.text = formattedJsonString;
            setState(() {});
          },
        );
      },
    );
  }

  Future<void> write(String md5MapFileContent) async {
    TranslateEntity entity = entitys[selectIndex];
    String fileName = "${entity.code}.json";
    String targetFile = "${targetDir}/$fileName";
    Map<String, dynamic> md5Map = json.decode(md5MapFileContent);

    if (!(await FFile.isExistFile(targetFile))) {
      File? file = await FFile.createFile(targetFile);
      if (file != null) {
        await FFile.writeContentByFile(file: file, content: "{\n}");
      }
    }

    String targetFileContent = await FFile.readAsString(targetFile);
    Map<String, dynamic> targetFileMap = json.decode(targetFileContent);

    convertFile("", targetFileMap, md5Map);

    String jsonMap = json.encode(targetFileMap);

    final jsonObject = json.decode(jsonMap);
    jsonMap = JsonEncoder.withIndent('  ').convert(jsonObject);

    bool success = await FFile.writeContentByPath(
        filePath: targetFile, content: jsonMap, mode: FileMode.write);
    SmartDialog.showToast("写入状态: $success");
  }

  void convertFile(String outKey, Map<String, dynamic> targetFileMap,
      Map<String, dynamic> md5Map) {
    targetFileMap.forEach((key, value) {
      String inKey = md5.convert(utf8.encode("$outKey$key")).toString();
      if (value is String) {
        if (md5Map.containsKey(inKey)) {
          targetFileMap[key] = md5Map[inKey];
        }
      } else if (value is Map) {
        Map<String, dynamic> valueMap = value as Map<String, dynamic>;
        convertFile(inKey, valueMap, md5Map);
      }
    });
  }
}
